#!/usr/bin/env zsh

function __zgenom_path_contains() {
    setopt localoptions nonomatch nocshnullglob nonullglob;
    [ -e "$1"/[^_]*"$2"(.,@[1]) ]
}

function __zgenom_source() {
    local source_file="${1}"
    local repo_id

    if [[ ! "${ZGEN_LOADED[@]}" =~ "${source_file}" ]]; then
        if [[ -z "${repo}" ]]; then
            repo_id="/${${source_file:h}:t}"
        elif [[ "${dir}" = *ohmyzsh* ]] || [[ "${dir}" = *oh-my-zsh* ]]; then
            repo_id="${repo}/${file}"
        else
            repo_id="${repo}"
        fi

        ZGEN_LOADED+=("${source_file}")
        ZGENOM_LOADED+=("${repo_id}")

        if [[ -d "$dir/functions" ]]; then
            __zgenom_add_to_fpath "$dir/functions"
        else
            __zgenom_add_to_fpath "${source_file:h}"
        fi

        zsh_loaded_plugins+=( "$repo_id" )
        set -- && ZERO="${source_file}" source "${source_file}"
    fi
}

function __zgenom_completion() {
    if [[ -d $location ]]; then
        __zgenom_add_to_fpath $location
    elif [[ -f $location && -d "${location:h}" ]]; then
        __zgenom_add_to_fpath "${location:h}"
    elif [[ -n $repo ]]; then
        __zgenom_err "Failed to find '$file' in '$repo'. Couldn't add completion"
    else
        __zgenom_err "Failed to add completion for ${dir:-$location}"
    fi
}

function __zgenom_add_to_fpath() {
    local completion_path="${1}"

    # Add the directory to ZGEN_COMPLETIONS array if not present
    if [[ ! "${ZGEN_COMPLETIONS[@]}" =~ ${completion_path} ]]; then
        ZGEN_COMPLETIONS+=("${completion_path}")
        fpath=("${completion_path}" $fpath)
    fi
}

function zgenom-load() {
    local completion pin
    zparseopts -D -E -completion=completion -pin=pin || return
    local location dir
    if [[ "$#" == 0 ]]; then
        __zgenom_err '`load` requires at least one parameter:'
        __zgenom_err '`zgenom load <repo> [location] [branch] [--location]`'
        return
    elif [[ "$#" == 1 && ("${1[1]}" == '/' || "${1[1]}" == '.' ) ]]; then
        location="${1}"
        if [[ -d "$location" ]]; then
            dir="$location"
        else
            dir="${location:h}"
        fi
    else
        local repo="${1}"
        local file="${2}"
        local branch="${3}"
        dir="$(__zgenom_clone_dir ${repo} --branch ${branch})"
        location="${dir}/${file}"
        location=${location%/}

        zgenom-clone "${repo}" "${branch}" $pin || return
    fi

    # Don't source, just fpath
    if [[ -n $completion ]]; then
        __zgenom_completion
        # Should bin be added?
        # Not for now since the bins should probably be only added when the plugin is loaded.
        # If only the bins should be added `zgenom bin <repo>` can be used instead.
        return

    # source the file
    elif [[ -f "${location}" ]]; then
        __zgenom_source "${location}"

    # Prezto modules have init.zsh files
    elif [[ -f "${location}/init.zsh" ]]; then
        __zgenom_source "${location}/init.zsh"

    elif [[ -f "${location}.zsh-theme" ]]; then
        __zgenom_source "${location}.zsh-theme"

    elif [[ -f "${location}.theme.zsh" ]]; then
        __zgenom_source "${location}.theme.zsh"

    elif [[ -f "${location}.zshplugin" ]]; then
        __zgenom_source "${location}.zshplugin"

    elif [[ -f "${location}.zsh.plugin" ]]; then
        __zgenom_source "${location}.zsh.plugin"

    # Classic ohmyzsh plugins have foo.plugin.zsh
    elif __zgenom_path_contains "${location}" ".plugin.zsh" ; then
        for script (${location}/*\.plugin\.zsh(N)) __zgenom_source "${script}"

    elif __zgenom_path_contains "${location}" ".zsh" ; then
        for script (${location}/*\.zsh(N)) __zgenom_source "${script}"

    elif __zgenom_path_contains "${location}" ".sh" ; then
        for script (${location}/*\.sh(N)) __zgenom_source "${script}"

    # Completions
    elif [[ -d "${location}" ]]; then
        __zgenom_add_to_fpath "${location}"

    else
        if [[ -d ${dir:-$location} ]]; then
            __zgenom_err "Failed to load ${dir:-$location} -- ${file}"
        else
            __zgenom_err "Failed to load ${dir:-$location}"
        fi
        return
    fi

    if [[ $ZGENOM_AUTO_ADD_BIN -eq 1 ]] && [[ -d "$dir/bin" ]]; then
        zgenom-bin "$repo" bin "$branch"
    fi
}

zgenom-load $@
